﻿using Consul;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.Configuration;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using HECore.ServiceFrame.Models;
using Microsoft.Extensions.DependencyInjection;

namespace HECore.ServiceFrame.Extensions
{
    /// <summary>
    /// 框架扩展：ApplicationBuilder
    /// </summary>
    public static class ApplicationBuilderExtensions
    {
        /// <summary>
        /// 框架扩展：使用Consul
        /// </summary>
        /// <param name="app"></param>
        /// <returns></returns>
        public static IApplicationBuilder FrameUseConsul(this IApplicationBuilder app)
        {
            var configuration = (IConfiguration)app.ApplicationServices.GetService(typeof(IConfiguration));

            var FrameConfig = new FrameConfig()
            {
                Service = new FrameConfigService()
                {
                    IP = configuration["FrameConfig:Service:IP"],
                    Name = configuration["FrameConfig:Service:Name"],
                    Port = int.Parse(configuration["FrameConfig:Service:Port"]),
                },
                Consul = new FrameConfigConsul()
                {
                    Address = configuration["FrameConfig:Consul:Address"],
                },
                Fabio = new FrameConfigFabio()
                {
                    Tagprefix = configuration["FrameConfig:Fabio:Tagprefix"],
                },
            };

            var ConsulClient = new ConsulClient(x => x.Address = new Uri(FrameConfig.Consul.Address));
            var HttpCheck = new AgentServiceCheck()
            {
                //服务启动多久后注册
                DeregisterCriticalServiceAfter = TimeSpan.FromSeconds(5),
                //健康检查时间间隔，或者称为心跳间隔
                Interval = TimeSpan.FromSeconds(10),
                //健康检查地址
                HTTP = $"http://{FrameConfig.Service.IP}:{FrameConfig.Service.Port}/health",
                //健康检查超时时间
                Timeout = TimeSpan.FromSeconds(5)
            };
            var Registration = new AgentServiceRegistration()
            {
                Checks = new[] { HttpCheck },
                ID = FrameConfig.Service.IP + ":" + FrameConfig.Service.Port,
                Name = FrameConfig.Service.Name,
                Address = FrameConfig.Service.IP,
                Port = FrameConfig.Service.Port,
                //添加 urlprefix-/servicename 格式的 tag 标签，以便 Fabio 识别
                Tags = new[] { $"{FrameConfig.Fabio.Tagprefix}/{FrameConfig.Service.Name} strip=/{FrameConfig.Service.Name}" }
            };
            ////服务启动时注册，内部实现其实就是使用 Consul API 进行注册（HttpClient发起）
            ConsulClient.Agent.ServiceRegister(Registration).Wait();

            return app;
        }

        /// <summary>
        /// 框架扩展：使用Swagger
        /// </summary>
        /// <param name="app"></param>
        /// <returns></returns>
        public static IApplicationBuilder FrameUseSwaggerUI(this IApplicationBuilder app)
        {
            var Configuration = (IConfiguration)app.ApplicationServices.GetService(typeof(IConfiguration));

            bool IsEnable = bool.Parse(Configuration["FrameConfig:Swagger:IsEnable"]);
            if (IsEnable)
            {
                app.UseSwagger();

                app.UseSwaggerUI(option =>
                {
                    option.SwaggerEndpoint("/swagger/v1/swagger.json", "v1");
                });
            }
            return app;
        }
    }
}
